import React from 'react';
import _ from 'underscore';
import cx from 'classnames';
import ReactPager from 'react-pagers';
import { List } from 'immutable';
import $ from 'jquery';

import GridWidget from 'lib/components/GridWidget.jsx'

import tips from '../common/indicator-tips.jsx';

import { Columns, iOSNoColumns } from './Constant.es6';

export default class DataFetcherView extends React.Component {
  constructor(props, context) {
    super(props, context);

    this.state = {
      currentPage: 0,
      pageSize: 5,
    }; // state

    this.tableColumns = [
      {
        key:'appVersionName',
        className:'pure-u w19',
        title: '版本号'
      }, {
        key:'all',
        className:'pure-u w19',
        title: '全选',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          let editableKeys = this.getEditableColumns()
            , settings = _.pick.call(_, rowValue.settings, editableKeys.toJS())
            , checked = _.size(settings) && _.every(settings, p => p);

          return (
            <label>
              <input
                type="checkbox"
                checked={ checked }
                onChange={ this.batchStatusChangingHandler.bind(this, rowValue, rowIndex) }
                disabled={ this.getColumnDisabled(rowValue) } />
            </label>
          );
        }
      }, {
        key:'switch.http',
        className:'pure-u w19',
        title: '网络请求详情',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          return (
            <label>
              <input
                type="checkbox"
                checked={ this.props.data.getIn(['app', 'settings', 'switch.http']) ? rowValue.settings['switch.http'] : false }
                onChange={ this.statusChangingHandler.bind(this, rowValue, rowIndex, 'switch.http') }
                disabled={ this.getColumnDisabled(rowValue, 'switch.http') } />
            </label>
          );
        }
      }, {
        key:'switch.activity',
        className:'pure-u w19',
        title: '交互详情',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          return (
            <label>
              <input
                type="checkbox"
                checked={ this.props.data.getIn(['app', 'settings', 'switch.activity']) ? rowValue.settings['switch.activity'] : false }
                onChange={ this.statusChangingHandler.bind(this, rowValue, rowIndex, 'switch.activity') }
                disabled={ this.getColumnDisabled(rowValue, 'switch.activity') } />
            </label>
          );
        }
      }, {
        key:'switch.ajax',
        className:'pure-u w19',
        title: 'Ajax 请求',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          return (
            <label>
              <input
                type="checkbox"
                checked={ this.props.data.getIn(['app', 'settings', 'switch.ajax']) ? rowValue.settings['switch.ajax'] : false }
                onChange={ this.statusChangingHandler.bind(this, rowValue, rowIndex, 'switch.ajax') }
                disabled={ this.getColumnDisabled(rowValue, 'switch.ajax') } />
            </label>
          );
        }
      }, {
        key:'switch.webview',
        className:'pure-u w19',
        title: 'WebView 页面',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          return (
            <label>
              <input
                type="checkbox"
                checked={ this.props.data.getIn(['app', 'settings', 'switch.webview']) ? rowValue.settings['switch.webview'] : false }
                onChange={ this.statusChangingHandler.bind(this, rowValue, rowIndex, 'switch.webview') }
                disabled={ this.getColumnDisabled(rowValue, 'switch.webview') } />
            </label>
          );
        }
      }, {
        key:'switch.crash',
        className:'pure-u w19',
        title: '崩溃详情',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          return (
            <label>
              <input
                type="checkbox"
                checked={ this.props.data.getIn(['app', 'settings', 'switch.crash']) ? rowValue.settings['switch.crash'] : false }
                onChange={ this.statusChangingHandler.bind(this, rowValue, rowIndex, 'switch.crash') }
                disabled={ this.getColumnDisabled(rowValue, 'switch.crash') } />
            </label>
          );
        }
      }, {
        key:'switch.anr',
        className:'pure-u w19',
        title: 'ANR 详情',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          return (
            <label>
              <input
                type="checkbox"
                checked={ this.props.data.getIn(['app', 'settings', 'switch.anr']) ? rowValue.settings['switch.anr'] : false }
                onChange={ this.statusChangingHandler.bind(this, rowValue, rowIndex, 'switch.anr') }
                disabled={ this.getColumnDisabled(rowValue, 'switch.anr') } />
            </label>
          );
        }
      }, {
        key:'switch.frame',
        className:'pure-u w19',
        title: '卡顿数据',
        render: (cellValue, rowValue, rowIndex, columnIndex) => {
          return (
            <label>
              <input
                type="checkbox"
                checked={ this.props.data.getIn(['app', 'settings', 'switch.frame']) ? rowValue.settings['switch.frame'] : false }
                onChange={ this.statusChangingHandler.bind(this, rowValue, rowIndex, 'switch.frame') }
                disabled={ this.getColumnDisabled(rowValue, 'switch.frame') } />
            </label>
          );
        }
      }
    ]; // this.tableColumns

    let filteredColumns = _.chain($('div.menu a'))
                           .map(p => {
                             let $item = $(p);
                             if (!$item.find('> *').length) {
                               return $item.text().trim();
                             } else {
                               return null;
                             }
                           })
                           .filter(p => p)
                           .value();

    this.tableColumns = _.chain(this.tableColumns);

    let noColumns = this.getNoColumns();
    if (noColumns.length) {
      this.tableColumns = this.tableColumns
                              .reject(p => noColumns.indexOf(p.key) !== -1);
    }

    if (BlueWare.isIOS) {
      this.tableColumns = this.tableColumns
                              .reject(p => iOSNoColumns.includes(p.key));
    }

    let className = `pure-u w1${ this.tableColumns.size().value() }`;
    this.tableColumns = this.tableColumns
                            .each(p => p.className = className)
                            .value();
  } // constructor

  getNoColumns() {
    let filteredColumns = _.chain($('div.menu a'))
                           .map(p => {
                             let $item = $(p);
                             if (!$item.find('> *').length) {
                               return $item.text().trim();
                             } else {
                               return null;
                             }
                           })
                           .filter(p => p)
                           .value();

    let noColumns = [];

    if (!_.find(filteredColumns, p => p.indexOf('Ajax') !== -1)) {
      noColumns.push('switch.ajax');
    }
    if (!_.find(filteredColumns, p => p.indexOf('ANR') !== -1)) {
      noColumns.push('switch.anr');
    }

    return noColumns;
  } // getNoColumns

  getEditableColumns() {
    if (!this.props.isEditing) {
      return new List();
    }

    let { data } = this.props
      , settings = data.getIn(['app', 'settings'])
                       .filter((v, k) => v && Columns.includes(k));

    return settings.keySeq();
  } // getEditableColumns

  getColumnDisabled(rowValue, key) {
    if (key) {
      let checked = this.props.data.getIn(['app', 'settings', key]);

      return !this.props.isEditing || !checked;
    } else {
      let keys = this.getEditableColumns();

      return !this.props.isEditing || !keys.count();
    }
  } // getColumnDisabled

  handlePageActiveChange(pageNumber) {
    this.setState({
      currentPage: pageNumber - 1
    });
  } // handlePageActiveChange

  allPropertyChangingHandler({ target: { checked } }) {
    let { allPropertyChanging, data } = this.props
      , appId = data.getIn(['app', 'appId'])
      , appVersionId = data.getIn(['app', 'appVersionId'])
      , value = checked ? '1' : '0';

    let changes = {};
    Columns.forEach(key => {
      let changeKey = `${ appId }:${ appVersionId }:${ key }`;
      changes[changeKey] = `${ changeKey }:${ value }`;
    });

    if (allPropertyChanging) {
      allPropertyChanging(value, changes);
    }
  } // allPropertyChangingHandler

  columnStatusChangingHandler(key, { target: { checked } }) {
    let { columnPropertyChanging, data } = this.props
      , changeKey = `${ data.getIn(['app', 'appId']) }:${ data.getIn(['app', 'appVersionId']) }:${ key }`
      , value = checked ? '1' : '0';

    let changes = {
      [changeKey]: `${ changeKey }:${ value }`
    };

    if (columnPropertyChanging) {
      columnPropertyChanging(key, value, changes);
    }
  } // columnStatusChangingHandler

  batchStatusChangingHandler(obj, index, { target: { checked } }) {
    let { batchPropertyChanging } = this.props
      , value = checked ? '1' : '0'
      , editableKeys = this.getEditableColumns()
      , keys = ['versions', this.state.pageSize * this.state.currentPage + index, 'settings'];

    let changes = {};
    _.chain(obj.settings)
      .pick((v, k) => editableKeys.includes(k))
      .each((v, k) => {
        let changeKey = `${ obj.appId }:${ obj.appVersionId }:${ k }`;
        changes[changeKey] = `${ changeKey }:${ value }`;
      });

    if (batchPropertyChanging) {
      batchPropertyChanging(keys, value, changes);
    }
  } //batchStatusChangingHandler

  statusChangingHandler(obj, index, key, { target: { checked } }) {
    let { propertyChanging } = this.props
      , value = checked ? '1' : '0'
      , keys = ['versions', this.state.pageSize * this.state.currentPage + index, 'settings', key]
      , changeKey = `${ obj.appId }:${ obj.appVersionId }:${ key }`
      , changes = {
        [changeKey]: `${ changeKey }:${ value }`
      };

    if (propertyChanging) {
      propertyChanging(keys, value, changes);
    }
  } // statusChangingHandler

  renderTableHeader(column, isHeader, callback, options) {
    if (!isHeader || !options.columnIndex) {
      return callback();
    }

    let { isEditing } = this.props
      , settings = this.props
                       .data
                       .getIn(['app', 'settings'])
                       .filter((v, k) => Columns.includes(k));

    switch (column.key) {
      case 'all':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.count() && settings.every(p => p) }
              onChange={ this.allPropertyChangingHandler.bind(this) }
              disabled={ !isEditing } />
            全选
          </label>
        );
      case 'switch.http':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.get('switch.http') || false }
              onChange={ this.columnStatusChangingHandler.bind(this, 'switch.http') }
              disabled={ !isEditing } />
            网络请求详情
          </label>
        );
      case 'switch.activity':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.get('switch.activity') || false }
              onChange={ this.columnStatusChangingHandler.bind(this, 'switch.activity') }
              disabled={ !isEditing } />
            交互详情
          </label>
        );
      case 'switch.ajax':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.get('switch.ajax') || false }
              onChange={ this.columnStatusChangingHandler.bind(this, 'switch.ajax') }
              disabled={ !isEditing } />
            Ajax 请求
          </label>
        );
      case 'switch.webview':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.get('switch.webview') || false }
              onChange={ this.columnStatusChangingHandler.bind(this, 'switch.webview') }
              disabled={ !isEditing } />
            WebView 页面
          </label>
        );
      case 'switch.crash':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.get('switch.crash') || false }
              onChange={ this.columnStatusChangingHandler.bind(this, 'switch.crash') }
              disabled={ !isEditing } />
            崩溃详情
          </label>
        );
      case 'switch.anr':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.get('switch.anr') || false }
              onChange={ this.columnStatusChangingHandler.bind(this, 'switch.anr') }
              disabled={ !isEditing } />
            ANR 详情
          </label>
        );
      case 'switch.frame':
        return (
          <label>
            <input
              type="checkbox"
              checked={ settings.get('switch.frame') || false }
              onChange={ this.columnStatusChangingHandler.bind(this, 'switch.frame') }
              disabled={ !isEditing } />
            卡顿数据
          </label>
        );
      default:
        return callback();
    }
  } // renderTableHeader

  renderTable() {
    let { isEditing } = this.props
      , data = this.props.data.get('versions')
      , pageCount = Math.ceil(data.count() * 1.0 / this.state.pageSize);

    if (pageCount <= this.state.currentPage || this.state.currentPage >= pageCount) {
      this.state.currentPage = 0;
    }

    let itemBeginIndex = this.state.pageSize * this.state.currentPage
      , itemEndIndex = itemBeginIndex + this.state.pageSize
      , filteredData = data.filter((p, i) => i >= itemBeginIndex && i < itemEndIndex);

    return (
      <div key="table" className="pure-g">
        <div className="pure-u-1">
          <GridWidget
            rowClassName="pure-g"
            contentRender={ this.renderTableHeader.bind(this) }
            cols={ this.tableColumns }
            store={{ data: filteredData.toJS() }} />
        </div>
        {
          pageCount <= 1 ? null : (
            <div className="pure-u-1">
              <ReactPager
                active={ this.state.currentPage + 1 }
                total={ pageCount }
                onChange={ this.handlePageActiveChange.bind(this) }
                className={{
                  container: 'text-right'
                }} />
            </div>
          )
        }
      </div>
    );
  } // renderTable

  render() {
    let data = this.props.data.get('versions')
      , pageCount = Math.ceil(data.count() * 1.0 / this.state.pageSize);

    return (
      <div className={ cx('pure-u-1', {
        'no-pages': pageCount === 1
      })}>
        <div className="fetcher-container">
          <h5 className="card-title sub">
            数据采集开关
            <sub style={{ fontSize: 12, marginLeft: 5 }}>
              { `(${ BlueWare.isAndroid ? 'Android' : 'iOS' } Agent 版本更新至 ${ BlueWare.isAndroid ? '3.0.5' : '2.2.4' } 以上可用)` }
            </sub>
            <i className="iconfont icon-tip" data-tip={tips.setting_versions}>
              &#xe663;
            </i>
          </h5>
          <div style={{ marginTop: -3 }}>
            { this.renderTable() }
          </div>
        </div>
      </div>
    );
  } // render
}
